﻿		#include "pch.h"
#include "class_log.h"
#include <fstream>
#include <chrono>
#include <iomanip>
#include <sstream>

/* --------------- 目录创建 --------------- */
#if __has_include(<filesystem>)
  #include <filesystem>
  namespace fs = std::filesystem;
  #define USE_FS
#elif defined(_WIN32)
  #include <direct.h>      // _mkdir
  #include <io.h>
#else
  #include <sys/stat.h>    // mkdir
  #include <unistd.h>
#endif

/* --------------- 辅助：获取当前时间字符串 --------------- */
static std::string local_time_str()
{
    using namespace std;
    using namespace std::chrono;

    auto now   = system_clock::now();
    auto ms    = duration_cast<milliseconds>(now.time_since_epoch()) % 1000;
    time_t tt  = system_clock::to_time_t(now);

    tm tm_snapshot;
#if defined(_WIN32)
    localtime_s(&tm_snapshot, &tt);
#else
    localtime_r(&tt, &tm_snapshot);
#endif

    ostringstream oss;
    oss << put_time(&tm_snapshot, "%Y-%m-%d %H:%M:%S");
    oss << '.' << setfill('0') << setw(3) << ms.count();
    return oss.str();
}

/* --------------- 辅助：创建多级目录 --------------- */
static bool create_dir_recursive(const std::string& path)
{
#ifdef USE_FS
    try { return fs::create_directories(path); }
    catch (...) { return false; }
#else
    std::string cmd = path;
    for (auto& ch : cmd) if (ch == '/') ch = PATH_SEP;
  #ifdef _WIN32
    return 0 == _mkdir(cmd.c_str());
  #else
    return 0 == mkdir(cmd.c_str(), 0755);
  #endif
#endif
}

/* --------------- 类实现 --------------- */
class_log::class_log() : w(0), r(0) {}
class_log::~class_log() { sync(); }

int class_log::init(std::string str_dz)
{
    std::lock_guard<std::mutex> g(mutex_log);
    str_log_dz = std::move(str_dz);
    if (!str_log_dz.empty() && str_log_dz.back() != '/')
        str_log_dz.push_back('/');
    return create_dir_recursive(str_log_dz) ? 0 : -1;
}

int class_log::insert(std::string head, std::string body)
{
    std::lock_guard<std::mutex> g(mutex_log);
    log_map_deque[std::move(head)].emplace_back(
        "[" + local_time_str() + "] " + body);
    return 0;
}

int class_log::msg(std::string txt)
{
    std::lock_guard<std::mutex> g(mutex_msg);
    msg_deque.emplace_back(std::move(txt));
    return 0;
}

int class_log::sync()
{
    /* 1. 刷日志文件 */
    {
        std::lock_guard<std::mutex> g(mutex_log);
        for (auto& kv : log_map_deque)
        {
            std::string full = str_log_dz + kv.first + ".log";
            std::ofstream ofs(full, std::ios::app);
            if (!ofs.is_open()) continue;
            for (auto& line : kv.second)
                ofs << line << '\n';
            kv.second.clear();
        }
    }

    /* 2. 刷 msg_deque（按题目原有语义，统一写进 msg.log） */
    {
        std::lock_guard<std::mutex> g(mutex_msg);
        if (!msg_deque.empty())
        {
            std::string full = str_log_dz + "msg.log";
            std::ofstream ofs(full, std::ios::app);
            for (auto& line : msg_deque)
                ofs << "[" << local_time_str() << "] " << line << '\n';
            msg_deque.clear();
        }
    }
    return 0;
}
